/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.mdm.web;

import java.util.Date;
import java.util.List;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.dd.plist.NSData;
import com.dd.plist.NSDictionary;
import com.dd.plist.NSObject;
import com.dd.plist.PropertyListParser;
import com.foreveross.bsl.mdm.ios.application.MdmCmdApplication;
import com.foreveross.bsl.mdm.ios.application.MdmEnrollApplication;
import com.foreveross.bsl.mdm.ios.application.MdmTaskApplication;
import com.foreveross.bsl.mdm.ios.application.vo.MdmCommandParamVo;
import com.foreveross.bsl.mdm.ios.application.vo.MdmEnrollmentVo;
import com.foreveross.bsl.mdm.ios.application.vo.MdmTaskVo;

/**
 * ios MDM server （apple规范）
 *
 * @author heyaowen
 * @version v1.0
 *
 * @date 2014-7-17
 *
 */
@Controller
@RequestMapping("/ios")
public class IOSMDMController {

    private transient final Log log = LogFactory.getLog(getClass());

	@Inject
	private MdmEnrollApplication mdmEnrollApplication;

	@Inject
	private MdmTaskApplication mdmTaskApplication;
	
	@Inject
	private MdmCmdApplication cmdApplication;


    @RequestMapping(value = "/checkin", method = RequestMethod.PUT)
    public void handleCheckinRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

        NSDictionary dictionary = (NSDictionary) PropertyListParser.parse(request.getInputStream()); // 请求体拿出构造成plist字典
        log.debug(dictionary.toXMLPropertyList());

        String messageType = dictionary.objectForKey("MessageType").toString();
        String udid = dictionary.objectForKey("UDID").toJavaObject().toString();
        MdmEnrollmentVo enrollmentVO = this.mdmEnrollApplication.getEntityByUdid(udid);

        if (messageType.equals("Authenticate")) { // 第一次握手
        	// 不存在的话，持久mdm签到对象
        	if(enrollmentVO == null) {
        		log.info("---创建签到对象...");
        		enrollmentVO = new MdmEnrollmentVo();
        		enrollmentVO.setUdid(udid);
        		enrollmentVO.setCreate_time(new Date());
        		enrollmentVO.setModified_time(new Date());
        		this.mdmEnrollApplication.saveEntity(enrollmentVO);
        	}
        } else if (messageType.equals("TokenUpdate")) { // 第二次握手
        	// mdm签到对象 则更新tokens
        	log.warn("---准备更新签到对象...");
        	if(enrollmentVO !=  null) {
        		enrollmentVO.setPushMagic(dictionary.objectForKey("PushMagic").toString());
        		NSData tokenData = ((NSData)dictionary.objectForKey("Token"));
        		// log.debug(tokenData.getBase64EncodedData());

        		enrollmentVO.setByteToken(tokenData.bytes());
        		enrollmentVO.setToken(Hex.encodeHexString(tokenData.bytes()));
        		enrollmentVO.setTopic(dictionary.objectForKey("Topic").toJavaObject().toString());
        		NSData unlockTokenData = (NSData)dictionary.objectForKey("UnlockToken");
        		// log.debug(unlockTokenData.getBase64EncodedData());

        		enrollmentVO.setUnlockToken(unlockTokenData.bytes());
        		enrollmentVO.setModified_time(new Date());
        		this.mdmEnrollApplication.updateEntity(enrollmentVO.getId(), enrollmentVO); // 这个id是domain反射时赋值给VO对象的
        	}
            log.debug("PushMagic>> " + enrollmentVO.getPushMagic() + " <<");
            log.debug("Token>> " + enrollmentVO.getToken() + " <<");
            log.debug("UnlockToken>> " + enrollmentVO.getUnlockToken() + " <<");
        }
    }

    @RequestMapping(value = "/server", method = {RequestMethod.PUT, RequestMethod.GET})
    public void handleSeverRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
        NSDictionary dictionary = (NSDictionary) PropertyListParser.parse(request.getInputStream());
        // log.warn("server request :\n" + dictionary.toXMLPropertyList());

        String status = dictionary.objectForKey("Status").toString();
        String udid = dictionary.objectForKey("UDID").toString();
        NSObject commandUUIDData = dictionary.objectForKey("CommandUUID");
        // 根据udid得到apns token 去查询tasks
        MdmEnrollmentVo enrollmentVO = this.mdmEnrollApplication.getEntityByUdid(udid);
        List<MdmTaskVo> mdmTasks = this.mdmTaskApplication.getEntityByToken_status(enrollmentVO.getToken(), "no");
        
        // first dev send “Status: Idle” plist，即拉取任务
        if ("Idle".equals(status) && commandUUIDData == null) { // step1 拉去task的plist交互
            if (mdmTasks.size() > 0 ) {
              MdmTaskVo topTask = mdmTasks.get(0);
              topTask.setStatus("run"); // 正在处理...
              this.mdmTaskApplication.updateEntity(topTask.getId(), topTask);
              String plist = new String(topTask.getCommand());
              // 应答第一个次MDM 指令
              response.getWriter().write(plist);

              log.debug("----------发送指令----------\n" + plist);
            } else {
                log.warn("UDID =" + udid + " device's task is not find...");
            }
        } else if (commandUUIDData != null) { //step2 拉去task的plist交互
            String CommandUUID = commandUUIDData.toString();
            log.debug("CommandUUID=" + CommandUUID);

            response.setStatus(200);
            List<MdmTaskVo> allTask = this.mdmTaskApplication.getEntityByToken_status_commandUUID(enrollmentVO.getToken(),
            		"run", CommandUUID);
            if (allTask.size() > 0) {
                MdmTaskVo topTask = allTask.get(0);
                topTask.setStatus("ok");
                topTask.setResult(dictionary.toXMLPropertyList().getBytes());
                topTask.setComplete_time(new Date());
                this.mdmTaskApplication.updateEntity(topTask.getId(), topTask);
            } else {
                log.warn("CommandUUID =" + CommandUUID + " task is not find...");
            }
        }
    }
    
    @RequestMapping(value = "/cmdTest", method = {RequestMethod.GET})
    public void testcmd(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	String cmd = request.getParameter("cmd");
    	String token = request.getParameter("token");
    	log.debug(" cmd=" + cmd + ", token=" + token);
    	
        this.cmdApplication.cmdHandler(cmd, token, new MdmCommandParamVo());
        response.setStatus(200);
        response.getWriter().write("ok...");
    }
}
